﻿using IBaseRepository;
using IServices;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
using SqlSugar;
using SqlSugarAndEntity;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Core;
using Core.ReflectionHelper;
using Core.ExpressionHelper;
using Core.JwtHelper;
using Core.PasswordHelper;
using Core.CommonModel;
using Core.AutoFac;

namespace Services
{
    public class UserService :BaseService<sys_userinfo>, IUserService,IAutoInject
    {
        private IUserRepository userRepository;
        private IConfiguration Configuration;
        private IOrgService orgService;
        public UserService(IUserRepository userRepository, IOrgService orgService, IConfiguration Configuration) :base(userRepository)
        {
            this.userRepository = userRepository;
            this.orgService = orgService;
            this.Configuration = Configuration;
        }

        public ResponseModel CreateUserInfo(sys_userinfo user, List<sys_usermaporg> map)
        {
            if (userRepository.GetUserInfo((a, b, c) => a.UserAccount == user.UserAccount, 1, 10).Items.FirstOrDefault() != null)
            {
                return new ResponseModel()
                {
                    code = ResponseTypeEnum.AccountAlreadyExists,
                    message = ResponseTypeEnum.AccountAlreadyExists
                };
            } 
            return CreateResponseModel<Action<ISqlSugarClient>>(userRepository.BeginTran, db =>
            {
                db.Insertable(user).ExecuteCommand();
                db.Insertable(map).ExecuteCommand();
            });
            //return CreateResponseModel(userRepository.InsertMany, user, map);
        }

        public ResponseModel DeleteUserInfo(Expression<Func<sys_userinfo, bool>> UserExp, Expression<Func<sys_usermaporg, bool>> MapExp)
        {
            return CreateResponseModel(userRepository.DeleteUserinfo, UserExp, MapExp);
        }

        public ResponseModel ExportUserinfo(Expression<Func<sys_userinfo, bool>> WhereCondition)
        {
            throw new NotImplementedException();
        }
        public ResponseModel GetUserInfo(string Name, string UserAccount, string UserPhone, string IdNumber, string OrgName, int page, int limit)
        {
            string PwdKey = Configuration.GetSection("AESKey").Value;
            ResponseModel res = new ResponseModel();
            Expression<Func<sys_userinfo, sys_usermaporg, sys_orginfo, bool>> OrginExp = null;
            Expression<Func<sys_userinfo, sys_usermaporg, sys_orginfo, bool>> WhereExp = OrginExp
                .AndIF(!string.IsNullOrEmpty(Name), (a, b, c) => a.UserName.Contains(Name))
                .AndIF(!string.IsNullOrEmpty(UserAccount), (a, b, c) => a.UserPhone.Contains(UserPhone))
                .AndIF(!string.IsNullOrEmpty(IdNumber), (a, b, c) => a.IdNumber.Contains(IdNumber))
                .AndIF(!string.IsNullOrEmpty(OrgName), (a, b, c) => c.OrgName.Contains(OrgName));
            var list = userRepository.GetUserInfo(WhereExp, page, limit);
            list.Items.ForEach(t =>
            {
                //把用户密码解密
                t.UserPassWord = AESHelper.AesDecrypt(t.UserPassWord, PwdKey);
            });
            res.model = list;
            return res; 
            //return CreateResponseModelByPage(userRepository.GetUserInfo, WhereExp, page, limit, ref total);
        }

        public ResponseModel ImportUserinfo(Stream s)
        {
            throw new NotImplementedException();
        }
        public ResponseModel Login(string account, string password)
        {
            string PwdKey = Configuration.GetSection("AESKey").Value;
            string RequestKey = JwtHelper.GetRequestKey();
            string RefreshKey = JwtHelper.GetRefreshKey();
            ResponseModel res = new ResponseModel();
            var userlist = userRepository.GetUserInfo((a, b, c) => a.UserAccount == account,1,10);
            if (userlist.Items.Count == 0)
            {
                res.code = ResponseTypeEnum.AccountNotExists;
                res.message = ResponseTypeEnum.AccountNotExists;
            }
            else
            {
                string AESPwd = AESHelper.AesEncrypt(password, PwdKey);
                var userinfo = userlist.Items.Where(t => t.UserPassWord == AESPwd).FirstOrDefault();
                if (userinfo != null)
                {
                    res.code = ResponseTypeEnum.LoginSucess;
                    res.message = ResponseTypeEnum.LoginSucess;
                    var userinfodic = ReflectionConvertHelper.ConvertObjectToDictionary(userinfo);
                    //生成请求token 测试用1分钟
                    string RequestToken = JwtHelper.CreateToken(RequestKey, userinfodic,10);
                    //生成RefreshToken
                    //RefreshToken的有效期，这里放置了一天,需要改几天就乘几
                    int LimitTime = 24 * 60;
                    string RefreshToken = JwtHelper.CreateToken(RefreshKey, userinfodic, LimitTime);
                    res.model = new { RequestToken = RequestToken, RefreshToken = RefreshToken };
                }
                else
                {
                    res.code = ResponseTypeEnum.PwdError;
                    res.message = ReflectionConvertHelper.GetEnumDescription(ResponseTypeEnum.PwdError);
                }
            }
            return res;

        }

        public ResponseModel RefreshToken(JObject value)
        {
            ResponseModel res = new ResponseModel();
            string RefreshToken = value.Value<string>("refreshToken");
            if (RefreshToken == null)
            {
                res.code = ResponseTypeEnum.NoToken;
                res.message = ResponseTypeEnum.NoToken;
                return res;
            }
            string RequestKey = JwtHelper.GetRequestKey();
            string RefreshKey = JwtHelper.GetRefreshKey();
            //验证token有效性
            var ValidateData = JwtHelper.ValidateJwt(RefreshKey, RefreshToken);
            //验证失败
            if (!ValidateData.flag)
            {
                res.code = ValidateData.responseType;
                res.message = ValidateData.responseType;
            }
            else
            {
                //验证成功
                //jwt先拆成3段
                var JwtData = JwtHelper.GetJwtInfo(RefreshToken);
                //jwt前两段重新用requestkey加密
                //string RequestToken = CreateEncodedSignature(RequestKey, JwtData.baseInfo, JwtData.info);
                res.code = ResponseTypeEnum.TokenSucess;
                res.message = ResponseTypeEnum.TokenSucess;
                var userinfo= JwtHelper.GetInfoByJwt(RefreshToken);
                long userid = userinfo.Value<long>("ID");
                var user = userRepository.GetUserInfo((a, b, c) => a.ID == userid, 1, 10).Items.FirstOrDefault();
                var userinfodic = ReflectionConvertHelper.ConvertObjectToDictionary(user);
                res.model = JwtHelper.CreateToken(RequestKey, userinfodic, 10);
                
                //res.model = CreateNewToken(RequestKey, JwtData, 10);
            }
            return res;
        }

        public ResponseModel UpdateUserInfo(sys_userinfo user, List<sys_usermaporg> map)
        {
            return CreateResponseModel(userRepository.UpdateUserInfo, user, map);
        }
        public ResponseModel GetRoleAuthorized(decimal roleId, int page, int limit)
        {
            return CreateResponseModel(userRepository.GetRoleAuthorized, roleId, page, limit);
        }

        public ResponseModel GetRoleNotAuthorized(decimal roleId, int page, int limit)
        {
            return CreateResponseModel(userRepository.GetRoleNotAuthorized, roleId, page, limit);
        }

        public ResponseModel UpdateUserPwd(decimal UserId,string OldPwd,string NewPwd)
        {
            ResponseModel res = new ResponseModel();
            var user = userRepository.GetInfo(t => t.ID == UserId).FirstOrDefault();
            if (user == null)
            {
                throw new Exception("用户不存在！");
            }
            string PwdKey = Configuration.GetSection("AESKey").Value;
            string AESPwd = AESHelper.AesEncrypt(OldPwd, PwdKey);
            if (user.UserPassWord != AESPwd)
            {
                res.code = ResponseTypeEnum.PwdError;
                return res;
            }
            else
            {
                string NewAes = AESHelper.AesEncrypt(NewPwd, PwdKey);
                return CreateResponseModel<Expression<Func<sys_userinfo, sys_userinfo>>,Expression<Func<sys_userinfo, bool>>,bool> (userRepository.Update, t => new sys_userinfo() { UserPassWord = NewAes }, t => t.ID == UserId);
            }
        }
    }
}
